package com.example.draw.algorithm;

import com.example.exception.BusinessException;
import com.example.pojo.LotteryPrize;
import java.math.BigDecimal;
import java.util.List;
import org.springframework.stereotype.Component;

/**
 * 概率抽奖算法
 * <p>
 * 该算法根据奖品的概率进行抽奖，概率总和不能超过1。<p>
 * 如果抽中库存不足的奖品，则返回默认奖品（谢谢参与）。
 */
@Component
public class ProbabilityLotteryAlgorithm implements LotteryAlgorithm {
    
    @Override
    public LotteryPrize draw(List<LotteryPrize> prizes) {
        // 计算总概率
        BigDecimal totalProbability = prizes.stream()
                                            .map(LotteryPrize::getProbability)
                                            .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        // 验证概率
        if (totalProbability.compareTo(BigDecimal.ONE) > 0) {
            throw new BusinessException("奖品概率配置错误,概率总和不能超过1");
        }
        
        // 生成随机数
        BigDecimal random = BigDecimal.valueOf(Math.random());
        BigDecimal temp = BigDecimal.ZERO;
        
        for (LotteryPrize prize : prizes) {
            temp = temp.add(prize.getProbability());
            if (random.compareTo(temp) <= 0) {
                if (prize.getRemainingStock() > 0) {
                    return prize;
                }
                break; // 库存不足则跳出
            }
        }
        
        // 返回默认奖品(谢谢参与)
        return getDefaultPrize(prizes);
    }
    
    @Override
    public String getAlgorithmType() {
        return "probability";
    }
    
    private LotteryPrize getDefaultPrize(List<LotteryPrize> prizes) {
        return prizes.stream()
            .filter(p -> "谢谢参与".equals(p.getName()))
            .findFirst()
            .orElseThrow(() -> new BusinessException("未配置默认奖品"));
    }

}
